home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene 96
/
Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso
/
misc
/
coding
/
vgacodng
/
part06_b.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-11-22
|
4KB
|
132 lines
program PCX2RAW;
uses crt;
type TPCXHeader = record { Header der PCX-Datei }
Manuf,Version,Encode,BitsPerPixel : byte;
X1,Y1,X2,Y2,Xres,Yres : integer;
Palette : array[0..47] of byte;
VideoMode,Planes : byte;
BytesPerLine : integer;
Reserved : array[0..59] of byte;
end;
PPCXPic = ^TPCXPic;
TPCXPic = record
Header : TPCXHeader; { Der Header }
Palette : array[0..767] of byte; { Die Palette }
Pixels : pointer; { Das Bild }
end;
var PCX_ : TPCXPic;
I : integer;
palf,rawf : file;
PCX,PAL,RAW : string;
procedure LoadPCX(FileName:string;var PCX:TPCXPic); { Lädt PCX-Datei }
var F : file;
Buf : array[0..1024] of byte;
BufPtr,Off,Size : word;
Code,Count : byte;
begin
assign(F,FileName);
reset(F,1);
blockread(F,PCX.Header,sizeof(PCX.Header)); { Header einlesen }
with PCX.Header do { und auswerten }
if (Manuf <> 10) or (Version <> 5) or (Encode <> 1) or
(BitsPerPixel <> 8) or (Planes <> 1) or
(BytesPerLine > 320) or (Y2 - Y1 > 199) then begin
PCX.Pixels := nil; { Bild kann nicht dargestellt werden }
exit;
end;
Size := PCX.Header.BytesPerLine * succ(PCX.Header.Y2 - PCX.Header.Y1);
{ Bildgröße ermitteln }
getmem(PCX.Pixels,Size);
if PCX.Pixels = nil then exit;
BufPtr := sizeof(Buf);
Off := 0; { Offset in der PCX-Datei }
while Off < Size do begin
if BufPtr >= sizeof(Buf) then begin
blockread(F,Buf,sizeof(Buf)); { Daten lesen }
BufPtr := 0;
end;
Code := Buf[BufPtr];
inc(BufPtr);
if Code shr 6 = 3 then begin { Dekomprimierung }
Count := Code and 63;
if BufPtr >= sizeof(Buf) then begin
blockread(F,Buf,sizeof(Buf));
BufPtr := 0;
end;
Code := Buf[BufPtr];
inc(BufPtr);
fillchar(mem[Seg(PCX.Pixels^):ofs(PCX.Pixels^)+Off],Count,Code);
inc(Off,Count);
end
else begin
mem[seg(PCX.Pixels^):ofs(PCX.Pixels^)+Off] := Code;
inc(Off);
end;
end;
if BufPtr >= sizeof(Buf) then begin
blockread(F,Buf,sizeof(Buf));
BufPtr := 0;
end;
Code := Buf[BufPtr];
inc(BufPtr);
if Code = 12 then begin
for Off := 0 to 767 do begin
if BufPtr >= sizeof(Buf) then begin
blockread(F,Buf,767-Off);
BufPtr := 0;
end;
PCX.Palette[Off] := Buf[BufPtr];
inc(BufPtr);
end;
end;
close(F);
end;
procedure FreePCX(var PCX:TPCXPic);
begin
if PCX.Pixels <> nil then
freemem(PCX.Pixels,PCX.Header.BytesPerLine*succ(PCX.Header.Y2-PCX.Header.Y1));
end;
begin
if paramcount <> 2 then halt;
PCX := paramstr(1); { Name der PCX-Datei }
RAW := paramstr(2); { Name der RAW-Datei }
PAL := RAW; { Name der PAL-Datei }
delete(PAL,pos('.',PAL),4); { eventuelle RAW-Endung entfernen }
PAL := PAL + '.pal'; { Endung '.PAL' anhängen }
LoadPCX(PCX,PCX_); { PCX-Datei laden }
if PCX_.Pixels = nil then begin { Fehler beim Laden }
writeln(#13#10'Error reading PCX file: ',PCX);
halt;
end;
asm mov ax,13h; int 10h end; { Modus 13h setzen }
port[$3C8] := 0; { Palette setzen }
for I := 0 to 767 do begin
PCX_.Palette[I] := PCX_.Palette[I] shr 2;
Port[$3C9] := PCX_.Palette[I];
end;
with PCX_ do { Bild darstellen }
for I := Header.Y1 to Header.Y2 do
Move(mem[seg(PCX_.Pixels^):ofs(PCX_.Pixels^)+I*Header.BytesPerLine],
mem[$A000:320*I],Header.X2 - Header.X1 + 1);
assign(rawf,RAW); { Dateien vorbereiten }
rewrite(rawf,1);
assign(palf,PAL);
rewrite(palf,1);
with PCX_ do { RAW-File schreiben }
for I := Header.Y1 to Header.Y2 do
blockwrite(rawf,mem[$A000:320*I],Header.X2 - Header.X1 + 1);
blockwrite(palf,PCX_.Palette,768); { PAL-File schreiben }
readkey;
close(rawf);
close(palf);
textmode(3);
end.